"""
Handlers.py
"""
#import datetime
#from django.contrib.auth import authenticate, login, logout
from django.db.models import Q
#from webservice_tools import utils
from webservice_tools.utils import BaseHandler
from webservice_tools.utils import strToBool
#from webservice_tools.response_util import ResponseObject
#from webservice_tools.decorators import login_required
from mainapp.models import * #@UnusedWildImport
import simplejson
#import sys
import utils


#Create your handlers here


class LevelHandler(BaseHandler):
    """
    Webservice call to handle the "Level" resource
    """
    allowed_methods = ('GET', )
    model = Level
    extra_fields = ('points', 'point_count', 'id', 'creator_username' )
    exclude = ('creator',)

    def read(self, request, ordinal , response):
        """
        Get a level by ID
        API Handler: GET /level/{ordinal}
        GET Params:
            None

        Returns:
            @level [level] level object
        """
        level = Level.objects.all()[int(ordinal)-1:ordinal]
        response.set(level=level)
        return response.send()

class WebLevelHandler(BaseHandler):
    """
    Webservice call to handle the "Level" resource
    """
    allowed_methods = ('GET', 'POST', 'PUT', 'DELETE')

    def read(self, request, id, response):
        """
        Get a level by ID
        API Handler: GET /weblevel/{id}
        GET Params:
            None

        Returns:
            @level [level] level object
        """
        level = Level.objects.filter(id=id)
        response.set(level=level)
        return response.send()

    def create(self, request, response):
        """
        Create a new level
        API Handler: POST /weblevel/
        POST Params:
            @points [json_str]
            @display_name
            @name
            @hill_color_base [str] Format: #FFFFFF (rbg)
            @hill_alpha_base [int] 0-255
            @hill_color_alt [str] Format: #FFFFFF (rbg)
            @hill_alpha_alt [int] 0-255
            @sky_color [str] Format: #FFFFFF (rbg)
            @sky_alpha [int] 0-255
            @sequence
            @active
            @gravity_factor_y
            @gravity_factor_x
            @time_to_complete
        """
        name = request.POST.get('name', '')
        display_name = request.POST.get('display_name', name)
        hill_color_base_str = request.POST.get('hill_color_base','#A2AFE2')
        hill_alpha_base = request.POST.get('hill_alpha_base', '255')
        hill_color_alt_str = request.POST.get('hill_color_alt','#A2AFE2')
        hill_alpha_alt = request.POST.get('hill_alpha_alt', '255')
        sky_color_str = request.POST.get('sky_color', '#A2AFE2')
        sky_alpha = request.POST.get('sky_alpha', '255')
        sequence = request.POST.get('sequence', '10')
        active = strToBool(request.POST.get('active', 'False'))
        gravity_factor_x = request.POST.get('gravity_factor_x', '0')
        gravity_factor_y = request.POST.get('gravity_factor_y', '0')
        time_to_complete = request.POST.get('time_to_complete', '60')
        points_json_str = request.POST.get('points', '[]')

        points = simplejson.loads(points_json_str)
        if len(points) < 5:
            return response.send(errors='A minimum of 5 points are requried')

        if not name:
            return response.send(errors='A unique "name" field is required')

        try:
            Level.objects.get(name=name)
            return response.send(errors='A unique "name" field is required')
        except Level.DoesNotExist:
            pass

        if not display_name:
            display_name = name

        r, g, b = utils.hex_to_rgb(hill_color_base_str)
        hill_color_base = Color.objects.get_or_create(r=r, g=g, b=b, a=hill_alpha_base)[0]

        r, g, b = utils.hex_to_rgb(hill_color_alt_str)
        hill_color_alt = Color.objects.get_or_create(r=r, g=g, b=b, a=hill_alpha_alt)[0]

        r, g, b = utils.hex_to_rgb(sky_color_str)
        sky_color  = Color.objects.get_or_create(r=r, g=g, b=b, a=sky_alpha)[0]

        level = Level.objects.create(name=name,
                                     display_name=display_name,
                                     hill_color_base=hill_color_base,
                                     hill_color_alt=hill_color_alt,
                                     sky_color=sky_color,
                                     sequence=sequence,
                                     active=active,
                                     gravity_factor_x=gravity_factor_x,
                                     gravity_factor_y=gravity_factor_y,
                                     time_to_complete=time_to_complete)
        for point in points:
            Point.objects.create(level=level, x=point['x'], y=point['y'])

        if request.user.is_authenticated:
            level.creator = request.user
            level.save()

        return response.send()

    def update(self, request, id, response):
        """
        Update a new level
        API Handler: PUT /weblevel/{id}
        PUT Params:
            @points [json_str]
            @display_name
            @name
            @hill_color_base [str] Format: #FFFFFF (rbg)
            @hill_alpha_base [int] 0-255
            @hill_color_alt [str] Format: #FFFFFF (rbg)
            @hill_alpha_alt [int] 0-255
            @sky_color [str] Format: #FFFFFF (rbg)
            @sky_alpha [int] 0-255
            @sequence
            @active
            @gravity_factor_y
            @gravity_factor_x
            @time_to_complete
        """
        name = request.PUT.get('name', '')
        display_name = request.PUT.get('display_name', name)
        hill_color_base_str = request.PUT.get('hill_color_base','#A2AFE2')
        hill_alpha_base = request.PUT.get('hill_alpha_base', '255')
        hill_color_alt_str = request.PUT.get('hill_color_alt','#A2AFE2')
        hill_alpha_alt = request.PUT.get('hill_alpha_alt', '255')
        sky_color_str = request.PUT.get('sky_color', '#A2AFE2')
        sky_alpha = request.PUT.get('sky_alpha', '255')
        sequence = request.PUT.get('sequence', '10')
        active = strToBool(request.PUT.get('active', 'False'))
        gravity_factor_x = request.PUT.get('gravity_factor_x', '0')
        gravity_factor_y = request.PUT.get('gravity_factor_y', '0')
        time_to_complete = request.PUT.get('time_to_complete', '60')
        points_json_str = request.PUT.get('points', '[]')

        points = simplejson.loads(points_json_str)
        if points and len(points) < 5:
            return response.send(errors='A minimum of 5 points are requried')

        if not name:
            return response.send(errors='A unique "name" field is required')

        level = Level.objects.get(id=id)

        if level.creator and (level.creator != request.user):
            return response.send(errors="This level is owned by someone else")
        if not level.creator and request.user.is_authenticated():
            level.creator = request.user

        try:
            Level.objects.get(Q(name=name), ~Q(id=level.id))
            return response.send(errors='A unique "name" field is required')
        except Level.DoesNotExist:
            pass

        if not display_name:
            display_name = name

        r, g, b = utils.hex_to_rgb(hill_color_base_str)
        level.hill_color_base = Color.objects.get_or_create(r=r, g=g, b=b, a=hill_alpha_base)[0]

        r, g, b = utils.hex_to_rgb(hill_color_alt_str)
        level.hill_color_alt = Color.objects.get_or_create(r=r, g=g, b=b, a=hill_alpha_alt)[0]

        r, g, b = utils.hex_to_rgb(sky_color_str)
        level.sky_color  = Color.objects.get_or_create(r=r, g=g, b=b, a=sky_alpha)[0]

        level.name=name
        level.display_name=display_name
        level.sequence=sequence
        level.active=active
        level.gravity_factor_x=gravity_factor_x
        level.gravity_factor_y=gravity_factor_y
        level.time_to_complete=time_to_complete
        level.save()

        if points:
            Point.objects.filter(level=level).delete()
            for point in points:
                Point.objects.create(level=level, x=point['x'], y=point['y'])

        return response.send()

class ColorHandler(BaseHandler):
    """
    Handler for individual color objects
    """

    model = Color
    extra_fields = ('hex_str',)

